<template>
  <div class="app-container">
    <div class="screen-container">
      <el-row :gutter="20">
        <el-col :span="6">
          <div class="tree-container">
            <div style="height: 40px"></div>
            <el-tree
              :data="channelTree"
              :props="defaultProps"
              :highlight-current="true"
              node-key="id"
              @node-click="handleNodeClick">
              <span class="custom-tree-node" slot-scope="{ node, data }">
                <span>
                  <i :class="getNodeIcon(data)" style="margin-right: 5px"></i>
                  {{ node.label }}
                </span>
                <span v-if="data.type === 'channel'" class="channel-status">
                  <el-tag size="mini" :type="data.status ? 'success' : 'info'">
                    {{ data.status ? '在线' : '离线' }}
                  </el-tag>
                </span>
              </span>
            </el-tree>
          </div>
        </el-col>
        <el-col :span="18">
          <div class="video-container">
            <div class="video-header">
              <div class="screen-controls">
                <div class="layout-controls">
                  <el-radio-group v-model="screenLayout" size="mini" @change="handleLayoutChange">
                    <el-radio-button label="1">单屏</el-radio-button>
                    <el-radio-button label="4">四分屏</el-radio-button>
                    <el-radio-button label="9">九分屏</el-radio-button>
                  </el-radio-group>
                </div>
                <div class="fullscreen-control">
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-full-screen"
                    @click="toggleFullscreen"
                  >{{ isFullscreen ? '退出全屏' : '全屏' }}</el-button>
                </div>
              </div>
            </div>
            <div class="video-wall">
              <div class="video-grid" :class="'layout-' + screenLayout">
                <div 
                  v-for="n in parseInt(screenLayout)" 
                  :key="n" 
                  class="video-cell"
                  :class="{ active: currentScreenIndex === n-1 }"
                  @click="selectScreen(n-1)"
                >
                  <div :id="'player' + (n-1)" class="player-container"></div>
                  <div v-if="!players[n-1]" class="video-placeholder">
                    {{ currentScreenIndex === n-1 ? '请选择要播放的通道' : '未播放' }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import { getChannelTree, startPlay } from "@/api/iot/channel";

export default {
  name: "ScreenDisplay",
  data() {
    return {
      screenLayout: "4",
      channelTree: [],
      currentChannel: null,
      currentScreenIndex: 0,
      players: [],
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      isFullscreen: false  // 添加全屏状态标记
    };
  },
  created() {
    this.getChannelTree();
  },
  mounted() {
    this.initPlayers();
    // 监听窗口大小变化，调整播放器大小
    window.addEventListener('resize', this.handleResize);
    // 监听全屏变化事件
    document.addEventListener('fullscreenchange', this.handleFullscreenChange);
    document.addEventListener('webkitfullscreenchange', this.handleFullscreenChange);
    document.addEventListener('mozfullscreenchange', this.handleFullscreenChange);
    document.addEventListener('MSFullscreenChange', this.handleFullscreenChange);
  },
  beforeDestroy() {
    // 销毁所有播放器实例
    this.destroyAllPlayers();
    window.removeEventListener('resize', this.handleResize);
    // 移除全屏变化事件监听
    document.removeEventListener('fullscreenchange', this.handleFullscreenChange);
    document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange);
    document.removeEventListener('mozfullscreenchange', this.handleFullscreenChange);
    document.removeEventListener('MSFullscreenChange', this.handleFullscreenChange);
  },
  methods: {
    /** 获取通道树数据 */
    getChannelTree() {
      getChannelTree().then(response => {
        this.channelTree = response.data;
      });
    },
    /** 处理节点点击 */
    handleNodeClick(data) {
      if (data.type === 'channel') {
        this.currentChannel = data;
        // 查找下一个可用的宫格
        const screenCount = parseInt(this.screenLayout);
        let nextIndex = this.currentScreenIndex;
        
        // 如果当前宫格已有播放内容，查找下一个空闲宫格
        if (this.players[nextIndex]) {
          // 查找下一个空闲宫格
          let hasEmptyCell = false;
          for (let i = 0; i < screenCount; i++) {
            const index = (nextIndex + i + 1) % screenCount;
            if (!this.players[index]) {
              nextIndex = index;
              hasEmptyCell = true;
              break;
            }
          }
          
          // 如果所有宫格都已占用，提示用户
          if (!hasEmptyCell) {
            this.$message.warning('所有窗口都已在播放，请先关闭某个窗口再播放新的视频');
            return;
          }
        }
        
        // 更新当前选中的宫格索引
        this.currentScreenIndex = nextIndex;
        // 播放视频
        this.playVideo(nextIndex, data);
      }
    },
    /** 获取节点图标 */
    getNodeIcon(data) {
      if (data.type === 'device') {
        return 'el-icon-video-camera';
      } else {
        return data.status ? 'el-icon-video-play' : 'el-icon-video-pause';
      }
    },
    /** 初始化播放器 */
    initPlayers() {
      this.destroyAllPlayers();
      const count = parseInt(this.screenLayout);
      this.players = new Array(count).fill(null);
      this.$nextTick(() => {
        this.handleResize();
      });
    },
    /** 销毁所有播放器 */
    destroyAllPlayers() {
      this.players.forEach((player, index) => {
        if (player) {
          player.destroy();
          this.players[index] = null;
        }
      });
    },
    /** 处理布局变化 */
    handleLayoutChange() {
      this.currentScreenIndex = 0;
      this.initPlayers();
    },
    /** 选择播放窗口 */
    selectScreen(index) {
      this.currentScreenIndex = index;
    },
    /** 播放视频 */
    async playVideo(index, channel) {
      // 如果该窗口已有播放器实例，先销毁
      if (this.players[index]) {
        this.players[index].destroy();
        this.players[index] = null;
      }

      try {
        // 获取设备ID
        const deviceId = channel.id.split('_')[1].split('/')[0];
        const channelId = channel.channelId;

        // 调用点播接口
        const res = await startPlay(deviceId, channelId);
        if (res.code != 200) {
          this.$message.error(res.msg || '点播失败');
          return;
        }

        // 创建新的播放器实例
        const player = new window.JessibucaPro({
          container: document.getElementById('player' + index),
          videoBuffer: 0.5,
          loadingText: '加载中...',
          debug: false,
          hotKey: false,
          autoWasm: true,
          heartTimeout: 10,
          timeout: 10,
          loadingTimeout: 10,
          hasAudio: false,
          supportDblclickFullscreen: false,
          showBandwidth: true,
          isNotMute: true,
          background: '#000000',
          decoder: '/plugins/jessibuca-pro/decoder-pro.js',
          wasmUrl: '/plugins/jessibuca-pro/decoder-pro.wasm',
          workerUrl: '/plugins/jessibuca-pro/jessibuca-pro.js',
          forceNoOffscreen: true,
          isFlv: true,
          hasVideo: true,
          operateBtns: {
            fullscreen: false,
            screenshot: false,
            play: false,
            audio: false,
            record: false,
          },
          videoFit: "fill",
          useWCS: true,
          useMSE: true,
          autoWasm: true,
          useOffscreen: false,
          useSIMD: true,
          useWorker: true,
          // 事件回调
          onPlayEvent: () => {
            console.log('开始播放');
          },
          onPauseEvent: () => {
            console.log('暂停播放');
          },
          onEndEvent: () => {
            console.log('播放结束');
          },
          onErrorEvent: (e) => {
            console.error('播放错误:', e);
            this.$message.error('播放出错：' + e);
          },
          onTimeUpdate: (ts) => {
            console.log('播放时间戳:', ts);
          },
          onMute: () => {
            console.log('静音');
          },
          onUnmute: () => {
            console.log('取消静音');
          },
          onFullscreen: () => {
            console.log('全屏');
          },
          onFullscreenExit: () => {
            console.log('退出全屏');
          },
          onInitFinish: () => {
            console.log('播放器初始化完成');
          },
          onLoad: () => {
            console.log('视频流加载成功');
          },
          onLoadingTimeout: () => {
            console.error('视频流加载超时');
            this.$message.warning('视频流加载超时，正在重试...');
            // 尝试重新播放
            if (res.data && res.data.ws_flv) {
              setTimeout(() => {
                player.play(res.data.ws_flv);
              }, 1000);  // 缩短重试间隔
            }
          },
          onWebsocketError: (e) => {
            console.error('WebSocket连接错误:', e);
          },
          onWebsocketClose: () => {
            console.log('WebSocket连接关闭');
          },
          // 增加更多调试事件
          onStats: (stats) => {
            console.log('播放器状态:', stats);
          },
          onWaiting: () => {
            console.log('等待数据中...');
          },
          onRender: () => {
            console.log('首帧渲染');
          }
        });

        // 保存播放器实例
        this.players[index] = player;

        // 开始播放前先检查地址
        if (res.data && res.data.ws_flv) {
          console.log('播放地址:', res.data.ws_flv);
          // 检查WebSocket地址是否可访问
          const ws = new WebSocket(res.data.ws_flv);
          ws.onopen = () => {
            console.log('WebSocket连接成功');
            ws.close();
            // 延迟一点时间再开始播放
            setTimeout(() => {
              player.play(res.data.ws_flv);
            }, 500);
          };
          ws.onerror = (error) => {
            console.error('WebSocket连接失败:', error);
            this.$message.error('视频流地址无法连接，请检查服务器状态');
          };
        } else {
          this.$message.error('未获取到播放地址');
        }
      } catch (error) {
        console.error('播放失败:', error);
        this.$message.error('播放失败：' + error.message);
      }
    },
    /** 处理窗口大小变化 */
    handleResize() {
      // 移除手动计算高度的逻辑，让容器自动填充
      this.$nextTick(() => {
        const players = this.players.filter(p => p);
        players.forEach(player => {
          if (player && player.resize) {
            player.resize();
          }
        });
      });
    },
    /** 切换全屏 */
    async toggleFullscreen() {
      try {
        const videoWall = document.querySelector('.video-wall');
        if (!this.isFullscreen) {
          // 进入全屏
          if (videoWall.requestFullscreen) {
            await videoWall.requestFullscreen();
          } else if (videoWall.webkitRequestFullscreen) {
            await videoWall.webkitRequestFullscreen();
          } else if (videoWall.mozRequestFullScreen) {
            await videoWall.mozRequestFullScreen();
          } else if (videoWall.msRequestFullscreen) {
            await videoWall.msRequestFullscreen();
          }
        } else {
          // 退出全屏
          if (document.exitFullscreen) {
            await document.exitFullscreen();
          } else if (document.webkitExitFullscreen) {
            await document.webkitExitFullscreen();
          } else if (document.mozCancelFullScreen) {
            await document.mozCancelFullScreen();
          } else if (document.msExitFullscreen) {
            await document.msExitFullscreen();
          }
        }
      } catch (error) {
        console.error('全屏切换失败:', error);
        this.$message.error('全屏切换失败');
      }
    },
    /** 处理全屏状态变化 */
    handleFullscreenChange() {
      this.isFullscreen = !!(document.fullscreenElement || 
                            document.webkitFullscreenElement || 
                            document.mozFullScreenElement || 
                            document.msFullscreenElement);
      // 全屏状态变化时，重新调整视频大小
      this.handleResize();
    }
  }
};
</script>

<style scoped>
.screen-container {
  height: calc(100vh - 120px);
  display: flex;
  flex-direction: column;
}

.screen-container .el-row {
  flex: 1;
  height: 100%;
}

.screen-container .el-col {
  height: 100%;
}

.tree-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 4px;
  padding-top: 0;
}

.tree-header {
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #eee;
}

.tree-container .el-tree {
  flex: 1;
  overflow: auto;
  padding: 10px;
}

.video-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #000;
  overflow: hidden;
}

.video-header {
  padding: 10px;
  background: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-shrink: 0;
}

.video-wall {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #000;
  overflow: hidden;
}

.video-grid {
  width: 100%;
  height: 100%;
  display: grid;
  gap: 1px;
  background: #333;
  margin: 0;
  padding: 0;
}

.video-grid.layout-1 {
  grid-template-columns: 1fr;
}

.video-grid.layout-4 {
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 1fr);
}

.video-grid.layout-9 {
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

.video-cell {
  position: relative;
  background: #1a1a1a;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.video-cell.active {
  border: 1px solid #409eff;
}

.player-container {
  width: 100% !important;
  height: 100% !important;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.player-container :deep(canvas) {
  width: 100% !important;
  height: 100% !important;
  object-fit: fill !important;
}

.video-placeholder {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #666;
  font-size: 14px;
  text-align: center;
  z-index: 1;
}

.screen-controls {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.layout-controls {
  text-align: center;
}

.fullscreen-control {
  position: absolute;
  right: 0;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.channel-status {
  font-size: 12px;
}

/* 全屏时的样式 */
.video-wall:fullscreen {
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  background: #000;
}

.video-wall:fullscreen .video-grid {
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
  gap: 1px;
}

.video-wall:fullscreen .video-cell {
  margin: 0;
  padding: 0;
}

.video-wall:fullscreen .player-container {
  margin: 0;
  padding: 0;
  width: 100% !important;
  height: 100% !important;
}

/* 兼容不同浏览器的全屏样式 */
.video-wall:-webkit-full-screen {
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  background: #000;
}

.video-wall:-moz-full-screen {
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  background: #000;
}

.video-wall:-ms-fullscreen {
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  background: #000;
}

/* 全屏时的控制按钮样式 */
.screen-controls .el-button [class^="el-icon-"] {
  font-size: 16px;
  vertical-align: middle;
}

.screen-controls .el-button {
  color: #606266;
}

.screen-controls .el-button:hover {
  color: #409EFF;
}

/* 确保视频墙在全屏时也能正确显示 */
.video-wall:fullscreen .video-grid {
  height: 100vh;
}

.video-wall:fullscreen .player-container {
  height: 100% !important;
}
</style> 